﻿using System;
using System.Threading;
using System.Web;
using System.Web.SessionState;

using Newtonsoft.Json;
using RaceList.activity.help;
using RaceList.activity.util;

namespace RaceList.activity.relay
{
    /// <summary>
    ///     _response.End();  //在Handler中强制终结request请求，会抛出异常
    ///     用户点击跑动，然后触发这个类，对Session中操作，将数据累加
    /// </summary>
    public class Relaying : IHttpHandler, IRequiresSessionState, IAuthWeixin
    {
        public void ProcessRequest(HttpContext context)
        {
            Init(context);
            AddScore();
        }

        /// <summary>
        ///     有大神说他不起作用，那就随便吧
        ///     获取一个值，该值指示其他请求是否可以使用 IHttpHandler 实例
        ///     如果 IHttpHandler 实例可再次使用,则为 true;否则为 false
        /// </summary>
        public bool IsReusable
        {
            get { return false; }
        }

        /// <summary>
        ///     将成绩更新到session中
        /// </summary>
        private void AddScore()
        {
            try
            {
                CallTimeOut();
            }
            catch (Exception ex)
            {
                SessionHelp.UserChengji.Dispose();
                WriteToClient(new ErrorMessage
                {
                    Status = Status.Error,
                    Exception = ex.Message,
                    IsShowException = _request.IsLocal, //如果是本地访问显示错误
                });
            }
        }

        private void Init(HttpContext context)
        {
            _context = context;
            _request = _context.Request;
            _response = _context.Response;
            _session = context.Session;
        }

        /// <summary>
        ///     向浏览器输出内容
        /// </summary>
        /// <param name="message"></param>
        public void WriteToClient(ErrorMessage message)
        {
            _response.Write(JsonConvert.SerializeObject(message));
        }

        #region field

        private readonly object _obj = new object();
        protected HttpContext _context;
        protected HttpRequest _request;
        protected HttpResponse _response;
        protected HttpSessionState _session;

        #endregion

        #region 10s以后需要干些操作

        public void InitRequestQuerystring()
        {
            double score = Convert.ToDouble(_request.Form["SumScore"].Replace("\n", "").Replace("M", "").Trim());
            int clickNum = Convert.ToInt32(_request.Form["ClickNum"]);
            UserChengji userChengji = SessionHelp.UserChengji;
            userChengji.Score = score;
            userChengji.ClickNum = clickNum;
            SessionHelp.UserChengji = userChengji;
        }

        public void CallTimeOut()
        {
            lock (_obj)
            {
                Thread.Sleep(new Random().Next(1, 500));
                if (IsSessionValid()) //只有session校验通过后，才进行一些其他的操作
                {
                    //保证只添加ji条记录
                    if (!IsDbValid()) //只有存在RelayId的时候检查字表的数量
                    {
                        int relayId = SessionHelp.UserChengji.RelayId;
                        SessionHelp.UserChengji.Dispose();
                        var message = new ErrorMessage
                        {
                            Finished = true,
                            Score = 0,
                            Status = Status.Error,
                            Exception = "手慢了0.01s，看看是谁抢先完成了帮帮跑！",
                            IsShowException = true,
                        };
                        if (relayId != 0)
                        {
                            message.Url = "Relayresult.aspx?" + Parameters.relay + "=" + relayId;
                        }
                        else
                        {
                            message.Url = SessionHelp.IndexUrl;
                        }

                        WriteToClient(message);
                        //_response.End();  //在Handler中强制终结request请求，会抛出异常
                        return;
                    }

                    InitRequestQuerystring();
                    double score = SessionHelp.UserChengji.Score;
                    if (!SessionHelp.UserChengji.IsAddedToDb) //是否添加过数据库中
                    {
                        int relayId = AddDb(); //添加到数据                        
                        SessionHelp.UserChengji.Dispose(); //清除session中的成绩
                        WriteToClient(new ErrorMessage
                        {
                            Score = score,
                            Finished = true,
                            Url = ("Relayresult.aspx?" + Parameters.relay + "=" + relayId).AddTimeStamp(),
                        });
                    }
                    else //如果添加过数据库的话，session中成绩信息都清除了，所以最好是让他返回首页
                    {
                        WriteToClient(new ErrorMessage
                        {
                            Score = score,
                            Finished = true,
                            Url = ("Relayindex.aspx?" + Parameters.relay + "=" + SessionHelp.CycleId).AddTimeStamp(),
                        });
                    }
                }
                else
                {
                    SessionHelp.UserChengji.Dispose();
                    WriteToClient(new ErrorMessage
                    {
                        Finished = true,
                        Url = ("Relayindex.aspx?" + Parameters.cycle + "=" + SessionHelp.CycleId).AddTimeStamp(),
                    });
                }
            }
        }

        /// <summary>
        ///     校验Activity_SubRelay中的数据条目,如果操作配置的值则返回false
        /// </summary>
        /// <returns></returns>
        private bool IsDbValid()
        {
            UserChengji userChengji = SessionHelp.UserChengji;
            if (userChengji.RelayId != 0)
            {
                if (RelayQuery.GetSubRelayList(userChengji.RelayId).Count + 1 >= ActivityConfig.MHalloweenTotalPerson)
                {
                    return false;
                }
            }
            return true;
        }

        private int AddDb()
        {
            UserChengji userChengji = SessionHelp.UserChengji;
            UserData userData = SessionHelp.UserData;

            try
            {
                if (userChengji.IsHelp) //根据IsHelp选择插入到那个数据库中
                {
                    var subrelay = new Activity_SubRelay
                    {
                        AddTime = DateTime.Now,
                        ClickNum = userChengji.ClickNum,
                        RelayId = userChengji.RelayId,
                        Score = userChengji.Score,
                        WeixinUserId = userData.WeixinUserId,
                    };
                    RelayQuery.AddSubRelay(subrelay);
                    return userChengji.RelayId;
                }
                else
                {
                    var relay = new Activity_Relay
                    {
                        AddTime = DateTime.Now,
                        ClickNum = userChengji.ClickNum,
                        Score = userChengji.Score,
                        SumScore = userChengji.Score,
                        WeixinUserId = userData.WeixinUserId,
                        CycleId = SessionHelp.CycleId,
                        SponsorId = SessionHelp.SponsorId == 0 ? null : SessionHelp.SponsorId,
                        EditTime = DateTime.Now
                    };
                    RelayQuery.AddRelay(relay);
                    return relay.Id;
                }
            }
            finally //不论失败与否，都是添加成功，然后第二次不能再添加
            {
                userChengji.IsAddedToDb = true;
            }
        }

        /// <summary>
        ///     只要检查Session中的UserData，CycleId！=0
        ///     判断session中数据是否符合要求
        ///     用于在计时器中添加到数据库之前的校验
        /// </summary>
        private bool IsSessionValid()
        {
            if (_context.Session != null)
            {
                return SessionHelp.CycleId != 0 && SessionHelp.ValidUserData();
            }
            return false;
        }

        #endregion
    }
}